<script setup lang="ts" name="Generate">
import Sortable from 'sortablejs';
import importPage from "./import.vue";
import { build } from "./generate";
import { listOptionselectApi } from '@/api/system/dict';
import { BOX_TYPE, GEN_LIST_JSON, GENERATE_JSON } from "@/views/tool/generate/const";

const router = useRouter();

const { proxy } = getCurrentInstance();

// 表单Id
const id = ref(null);

const genActive = ref('');

// 全部必填
const allRequired = ref(false);

// 代码生成所需数据
const generate = ref<GenerateRecord>({
  modular: "",
  tableName: "",
  folder: "",
  apiUrl: "",
  tableNotes: "",
  tableList: [],
});

// 保存的代码生成表格数据
const genList = ref<GenerateRecord[]>([]);

// 弹出层标题
const title = ref("");

// 编辑弹出层
const openImport = ref(false);

const genRules = ref({
  modular: [
    { required: true, message: "请输入模块权限", trigger: "blur" },
  ],
  tableName: [
    { required: true, message: "请输入表名", trigger: "blur" },
  ],
  tableNotes: [
    { required: true, message: "请输入表注释", trigger: "blur" },
  ],
  folder: [
    { required: true, message: "请输入目录", trigger: "blur" },
  ],
  apiUrl: [
    { required: true, message: "请输入接口地址", trigger: "blur" },
  ],
});

const tabRules = ref({
  columnName: [
    { required: true, message: "请输入字段名", trigger: "blur" },
  ],
  columnNotes: [
    { required: true, message: "请输入字段注释", trigger: "blur" },
  ],
  boxType: [
    { required: true, message: "请选择输入框类型", trigger: "blur" },
  ],
});

/** 查询获取代码生成数据 */
function getList() {
  const genListJson = localCache.getItem(GEN_LIST_JSON);

  if (genListJson) {
    genList.value = JSON.parse(genListJson);
  }

  const generateJson = localCache.getItem(GENERATE_JSON);

  if (generateJson) {
    generate.value = JSON.parse(generateJson);
    genActive.value = generate.value.tableName;
  } else {
    reset();
  }
}

// 字典类型列表
const dictTypeList = ref<DictRecord[]>([])

/** 获取字典类型列表 */
function getDictTypeList() {
  listOptionselectApi().then(response => {
    dictTypeList.value = response.data;
    dictTypeList.value.forEach(item => {
      item.label = item.dictName + ' - ' + item.dictType;
    });
  })
}

//设置拖动
function setSort() {
  const el = document.querySelector(".el-table__body-wrapper tbody");

  // @ts-ignore
  Sortable.create(el, {
    onEnd: ({ newIndex, oldIndex }: any) => {
      const targetRow = generate.value.tableList.splice(oldIndex, 1)[0];

      generate.value.tableList.splice(newIndex, 0, targetRow);
    },
  });
}

// 表单重置
function reset() {
  generate.value = {
    modular: "",
    tableName: "",
    folder: "",
    apiUrl: "",
    tableNotes: "",
    tableList: [],
  };
}

/** 全部必填 */
function changeAllRequired(val) {
  generate.value.tableList.forEach(item => {
    item.required = val;
  })
}

/** 保存数据 */
function saveGenerate() {
  const generateJson = JSON.stringify(generate.value);

  localCache.setItem(GENERATE_JSON, generateJson);
}

/** 保存表 */
function handleSaveGenList() {
  const genListIndex = genList.value.findIndex(item => item.tableName == generate.value.tableName);

  if (genListIndex > -1) {
    genList.value[genListIndex] = cloneDeep(generate.value);
  } else {
    if(generate.value.tableName){
      genList.value.unshift(cloneDeep(generate.value));
    }
  }

  const genListJson = JSON.stringify(genList.value);

  localCache.setItem(GEN_LIST_JSON, genListJson);
  genActive.value = generate.value.tableName;
}

/** 关闭弹窗 */
function closeDialog(option: any) {
  if (option.data) {
    generate.value.tableList = option.data;
  }
  openImport.value = false;
}

/** 新增表操作 */
function handleAddTabble() {
  handleSaveGenList();
  genActive.value = '';
  reset();
}

/** 新增按钮操作 */
function handleAdd(index) {
  const indNum = Number(index) || "";

  const generateRow: GeneraColumnRecord = {
    sId: new Date().getTime() + "" + indNum,
    colNo: null,
    columnName: null,
    columnNotes: null,
    columnType: null,
    isKey: false,
    boxType: 'input',
    required: true,
    dictType: '',
  }

  if (index || index === 0) {
    generate.value.tableList.splice(index + 1, 0, generateRow);
  } else {
    generate.value.tableList.push(generateRow);
  }
}

/** 选中代码生成表 */
function handleSelectGen(item) {
  generate.value = cloneDeep(item);
  genActive.value = generate.value.tableName;
}

/** 删除代码生成表 */
function handleDeleteGen(index) {
  genList.value.splice(index, 1);
  handleSaveGenList();
}

/** 导入按钮操作 */
function handleImport() {
  openImport.value = true;
  title.value = "导入接口数据";
}

/** 删除按钮操作 */
function handleDelete(row, index) {
  generate.value.tableList.splice(index, 1);
}

/** 预览操作按钮 */
async function handlePreview() {
  // @ts-ignore
  await proxy.$refs["genForm"].validate();
  // @ts-ignore
  await proxy.$refs["tabForm"].validate();
  router.push("/tool/generate/preview");
}

/** 生成按钮操作 */
async function handleExport() {
  // @ts-ignore
  await proxy.$refs["genForm"].validate();
  // @ts-ignore
  await proxy.$refs["tabForm"].validate();
  // @ts-ignore
  proxy.$modal.confirm("是否确认生成代码?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(() => {
    build(generate.value)
  }).catch(() => {
  });
}


watch(generate, () => {
      saveGenerate();
    },
    //深度监听
    { deep: true }
)

watch(() => generate.value.tableList, (val) => {
      if (val && val.length) {
        let isRequired = true;

        val.forEach((item, index) => {
          item.colNo = index + 1;
          if (!item.required) {
            isRequired = false;
          }
        })
        allRequired.value = isRequired;
      }
    },
    //深度监听
    { deep: true }
)

onMounted(() => {
  setSort();
})

getList();
getDictTypeList();
</script>

<template>
  <div class="app-container">
    <div class="back-item">
      <el-form :model="generate" ref="genForm" :rules="genRules" :inline="true" label-width="78px">
        <el-form-item label="表名" prop="tableName">
          <el-input
              v-model="generate.tableName"
              placeholder="请输入表名"
              clearable
          />
        </el-form-item>
        <el-form-item label="表注释" prop="tableNotes">
          <el-input
              v-model="generate.tableNotes"
              placeholder="请输入表注释"
              clearable
          />
        </el-form-item>
        <el-form-item label="模块权限" prop="modular">
          <el-input
              v-model="generate.modular"
              placeholder="请输入模块权限"
              clearable
          />
        </el-form-item>
        <el-form-item label="目录" prop="folder">
          <el-input
              v-model="generate.folder"
              placeholder="请输入名字"
              clearable
          />
        </el-form-item>
        <el-form-item label="接口地址" prop="apiUrl">
          <el-input
              v-model="generate.apiUrl"
              placeholder="请输入名字"
              clearable
          />
        </el-form-item>
      </el-form>
    </div>
    <div class="back-item">
      <div class="table-top mb8">
        <div class="title title-left">
          <el-select v-model="genActive" placeholder="请选择数据表" class="table-item-select">
            <el-option
              value="addTable"
              @click="handleAddTabble"
            >
              <span><icon-svg icon-name="Plus"/> 新增表</span>
            </el-option>
            <el-option
                :label="`${item.tableName} - ${item.tableNotes}`"
                :value="item.tableName"
                v-for="(item, index) in genList"
                :key="index"
                class="table-item-box"
                @click="handleSelectGen(item)"
            >
              <div class="table-item-left">{{ `${item.tableName} - ${item.tableNotes}` }}</div>
              <icon-svg
                  v-if="item.tableName != genActive"
                  icon-name="CircleClose"
                  @click.stop="handleDeleteGen(index)"
              />
            </el-option>
          </el-select>
        </div>
        <el-button
            type="info"
            plain
            icon="Download"
            @click="handleImport"
        >导入
        </el-button>
        <el-button
            type="primary"
            plain
            icon="Plus"
            @click="handleAdd"
        >新增
        </el-button>
        <el-button
            type="success"
            plain
            icon="View"
            @click="handlePreview"
        >预览
        </el-button>
        <el-button
            type="warning"
            plain
            icon="Download"
            @click="handleExport"
        >生成
        </el-button>
        <el-button
            plain
            icon="Download"
            @click="handleSaveGenList"
        >保存表
        </el-button>
      </div>
      <el-form :model="generate" ref="tabForm" :rules="tabRules" :inline="true">
        <el-table
            :data="generate.tableList"
            stripe
            row-key="sId"
            v-tablesticky
        >
          <el-table-column label="序号" align="center" width="55" prop="colNo" />
          <el-table-column label="字段名" align="center" prop="columnName" min-width="120">
            <template #default="scope">
              <el-form-item :prop="`tableList[${scope.$index}].columnName`" :rules="tabRules.columnName">
                <el-input
                    v-model="scope.row.columnName"
                    placeholder="请输入字段名"
                    clearable
                />
              </el-form-item>
            </template>
          </el-table-column>
          <el-table-column label="字段注释" align="center" prop="columnNotes" min-width="120">
            <template #default="scope">
              <el-form-item :prop="`tableList[${scope.$index}].columnNotes`" :rules="tabRules.columnNotes">
                <el-input
                    v-model="scope.row.columnNotes"
                    placeholder="请输入字段注释"
                    clearable
                />
              </el-form-item>
            </template>
          </el-table-column>
          <el-table-column label="编辑框" align="center" prop="boxType" min-width="120">
            <template #default="scope">
              <el-form-item :prop="`tableList[${scope.$index}].boxType`" :rules="tabRules.boxType">
                <el-select v-model="scope.row.boxType" placeholder="请选择编辑框类型">
                  <el-option :label="item.label" :value="item.value" v-for="(item, index) in BOX_TYPE" :key="index" />
                </el-select>
              </el-form-item>
            </template>
          </el-table-column>
          <el-table-column label="字段类型" align="center" prop="columnType" min-width="120">
            <template #default="scope">
              <el-input v-model="scope.row.columnType" placeholder="请输入字段类型" clearable />
            </template>
          </el-table-column>
          <el-table-column label="是否主键" align="center" prop="isKey" min-width="120">
            <template #default="scope">
              <el-checkbox v-model="scope.row.isKey" />
            </template>
          </el-table-column>
          <el-table-column label="是否必填" align="center" prop="required" min-width="120">
            <template #header="scope">
              {{ scope.column.label }}
              <el-switch v-model="allRequired" @change="changeAllRequired" />
            </template>
            <template #default="scope">
              <el-switch v-model="scope.row.required" />
            </template>
          </el-table-column>
          <el-table-column label="字典类型" align="center" prop="dictType" min-width="120">
            <template #default="scope">
              <el-select v-model="scope.row.dictType" placeholder="请选择字典类型" clearable>
                <el-option
                    :label="item.label"
                    :value="item.dictType"
                    v-for="(item, index) in dictTypeList"
                    :key="index"
                />
              </el-select>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" width="100" fixed="right">
            <template #default="scope">
              <el-tooltip content="新增" placement="top">
                <el-button
                    size="small"
                    link
                    icon="Plus"
                    @click="handleAdd(scope.$index)"
                />
              </el-tooltip>
              <el-tooltip content="删除" placement="top">
                <el-button
                    size="small"
                    link
                    icon="Delete"
                    @click="handleDelete(scope.row, scope.$index)"
                    class="text-danger"
                />
              </el-tooltip>
            </template>
          </el-table-column>
        </el-table>
      </el-form>
      <div class="line-magin" />
    </div>
    <import-page v-if="openImport" :title="title" @closeDialog="closeDialog" />
  </div>
</template>

<style lang="scss" scoped>
:deep(.el-table) {
  .cell {
    overflow: visible;
  }

  .el-form-item {
    width: 100%;
    margin-bottom: 0;
    margin-right: 0;

    .el-form-item__content {
      width: 100%;

      .el-input, .el-select {
        min-width: auto;
      }
    }
  }
}

.table-item-select {
  width: 240px;
}

.table-item-box {
  display: flex;
  align-items: center;
  padding: 6px 12px;

  .table-item-left {
    flex: 1;
    display: block;
  }
}
</style>
